<template>
  <!-- <button @click="router.push('/index')">自动账号密码登录</button> -->
  <iframe
    v-if="iframeUrl"
    id="discordId"
    ref="iframeInstance"
    :src="iframeUrl"
    frameborder="0"
    sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
    @load="onIframeLoad"
  ></iframe>

  <div
    v-else
    style="width: 100%; color: white; font-size: 30px; text-align: center; margin-top: 100px"
  >
    <span>第一次加载比较慢，请耐心等待...</span>
  </div>
</template>

<script setup>
import { ref, onBeforeUnmount, nextTick } from 'vue'
import axios from 'axios'
import { useRouter } from 'vue-router'
import { decrypt } from '../utils/crypto.js'
// import { resetWebsocket } from '../utils/resetWebsocket.js'
import Config from '@renderer/config'
import { ipc } from '../utils/index.js'

const router = useRouter()
const iframeInstance = ref(null)
const base = 'https://discord.com/'
const iframeUrl = ref('')
const timer = ref(null) // 计时器
const delayTime = 300 * 1000 // 延迟时间
let globalData = null // 全局数据
let currentGuilds = []
let globalToken = null

// 注销
const loginOut = () => {
  window.localStorage.clear()
  router.replace('/')
}

// 给iframe送token
const setToken = (token) => {
  const decryptToken = decrypt(token)
  iframeInstance.value.contentWindow &&
    iframeInstance.value.contentWindow.localStorage.setItem('token', JSON.stringify(decryptToken))
  return decryptToken
}

const onIframeLoad = () => {
  // hideSideBar() && hideDiscordMenu() // 只能限制在自己频道上
  setSomeStyleToIframe()
  rewriteGlobalData(globalData)
  getGuildChannel()
}

// 查找最大条数的数据
const findNearbyObjects = (array, gid, cid, count) => {
  // 根据关键字筛选出满足要求的对象
  const filteredObjects = array.filter(
    (obj) => obj.id === gid && obj.properties.system_channel_id === cid
  )

  // 如果没有找到满足条件的对象，直接返回最大数据
  if (filteredObjects.length === 0) {
    return array.slice(0, count)
  }

  // 找到目标对象在数组中的位置
  const index = array.findIndex((obj) => obj.id === gid && obj.properties.system_channel_id === cid)

  // 确定获取的前后数据的起始和结束索引
  let startIndex = Math.max(0, Math.floor(index - (count - 1) / 2))
  let endIndex = Math.min(array.length - 1, startIndex + count - 1)

  // 如果起始索引为 0，且 endIndex 不足 count 条数据，则修正 endIndex
  if (startIndex === 0 && endIndex !== count - 1) {
    endIndex = Math.min(count - 1, array.length - 1)
  }
  // 如果结束索引为数组最后一个元素的索引，且 startIndex 不足 count 条数据，则修正 startIndex
  if (endIndex === array.length - 1 && startIndex !== array.length - count) {
    startIndex = Math.max(0, array.length - count)
  }

  // 获取目标对象的前后数据
  const nearbyObjects = array.slice(startIndex, endIndex + 1)
  return nearbyObjects
}

/**
 * 重写discordwindow对象
 */
const rewriteGlobalData = async (data) => {
  // await nextTick()
  const app = iframeInstance.value.contentWindow
  app.__base__config__ = {
    run: function (t) {
      try {
        const parse = JSON.parse(t)
        if (parse.t.toUpperCase() === 'READY') {
          parse.d.guilds = findNearbyObjects(
            parse.d.guilds,
            data.guildId,
            data.channelId,
            data ? data.maxUser || 12 : 12
          )
          currentGuilds = parse.d.guilds // 记录当前的频道数据
          return JSON.stringify(parse)
        }
        // 删除服务器
        if (parse.t.toUpperCase() === 'GUILD_DELETE') {
          debugger
          removeGuildHandler(parse.d.id)
        }

        // 创建服务器
        if (parse.t.toUpperCase() === 'GUILD_CREATE') {
          createGuildHandler(parse.d)
        }

        return t
      } catch (err) {
        return t
      }
    },

    data: data
  }
}

// 禁止一些样式
const setSomeStyleToIframe = async () => {
  try {
    const response = await axios.get(`${Config.baseUrl}mjapp.json`)
    const { style } = response.data
    const iframeDocument =
      iframeInstance.value.contentDocument || iframeInstance.value.contentWindow.document
    const styleElement = iframeDocument.createElement('style')
    // 在 style 元素中写入样式规则
    const styleText = style
    styleElement.appendChild(iframeDocument.createTextNode(styleText))

    // 将 style 元素添加到 iframe 内部文档的 head 中
    iframeDocument.head.appendChild(styleElement)
  } catch (error) {
    //
  }
}

// 检查自家平台的登录, flag是否是定时器触发
const checkAccount = async (flag) => {
  const key = window.localStorage.getItem('__code__')
  const session = window.localStorage.getItem('__session__')

  if (!key) {
    loginOut()
    return false
  }
  ipc.send('login', {
    key: JSON.parse(key),
    session,
    external: {
      isTimer: flag
    }
  })
}

// 检查dis过期
const checkAccountByDiscord = async (token) => {
  const d = decrypt(token)
  try {
    await axios.get(`https://discord.com/api/v9/users/@me/billing/payment-sources`, {
      headers: {
        Authorization: d
      }
    })
    return true
  } catch (error) {
    console.log('登录已失效 checkAccountByDiscord')
    window.alert('登录已失效')
    loginOut()
    return false
  }
}

/**
 * 初始化，重新写方法
 */
const init = async (res) => {
  const { channelId, guildId, type, token, maxUser } = res
  if (channelId && guildId) {
    iframeUrl.value = base + 'channels/' + guildId + `/${channelId}`
  } else {
    iframeUrl.value = base + 'channels/@me'
  }
  globalData = {
    channelId,
    guildId,
    code: window.localStorage.getItem('__code__'),
    type,
    maxUser
  }
  await nextTick()
  globalToken = setToken(JSON.stringify(token))
  setTimeout(() => {
    timer.value && clearInterval(timer.value)
    timer.value = setInterval(() => {
      checkAccount(true)
    }, delayTime)
  }, delayTime)
}

// 移除频道
const removeGuildHandler = (id) => {
  const idx = currentGuilds.findIndex((v) => v.id === id)
  const item = currentGuilds[idx]
  if (!item) return
  if (
    item.id === globalData.guildId &&
    item.properties.system_channel_id === globalData.channelId
  ) {
    ipc.send('update-account-info', {
      channelId: '',
      guildId: '',
      key: JSON.parse(window.localStorage.getItem('__code__')),
      token: globalToken
    })
  }
}

/**
 * 创建频道
 * @param {*} data
 */
const createGuildHandler = (data) => {
  ipc.send('update-account-info', {
    channelId: data.properties.system_channel_id,
    guildId: data.id,
    key: JSON.parse(window.localStorage.getItem('__code__')),
    token: globalToken
  })
  currentGuilds.push(data)
}
// 获取discord菜单列表
// https://discord.com/api/v9/users/@me/guilds 调用方式同上
// init()
// checkAccount()
// 重写websorcket
// resetWebsocket()

// 关闭窗口操作
const getGuildChannel = () => {
  try {
    const iframeDocument =
      iframeInstance.value.contentDocument || iframeInstance.value.contentWindow.document
    const channel = iframeDocument.querySelector('[data-dnd-name="常规"]')
    const label = iframeDocument.querySelector('.name_c08dbc').innerText
    const url = channel.querySelector('a').href
    const arr = url.split('/')
    const guildId = arr[arr.length - 2]
    const channelId = arr[arr.length - 1]
    return {
      label,
      guildId,
      channelId
    }
  } catch (error) {
    return {}
  }
}

const setGuildChannel = () => {
  const data = getGuildChannel()
  ipc.send('set-guild-channel', {
    ...data,
    key: JSON.parse(window.localStorage.getItem('__code__'))
  })
}

ipc.on('get-guild-channel', setGuildChannel)


const loginResult = async (e, arg) => {
  const { success, data: response, isTimer } = arg
  if (!success) {
    window.alert('账号不存在')
    loginOut()
    return
  }
  const { code, data } = response
  if (code === 401) {
    // 自家平台被挤下线
    window.alert('登录已失效')
    loginOut()
    return
  }
  const { status, token } = data || {}
  if (!status) {
    window.alert('账号已注销')
    // 注销账号
    loginOut()
    return
  }
  // 去discord检查token是否过期
  const r = await checkAccountByDiscord(JSON.stringify(token))
  if (!r) {
    window.alert('账号已失效')
    loginOut()
    return
  }
  !isTimer && init(data)
}

ipc.on('login-result', loginResult)

onBeforeUnmount(() => {
  timer.value && clearInterval(timer.value)
  ipc.off('get-guild-channel', setGuildChannel)
  ipc.off('login-result', loginResult)
})

// ----------------- 初始化 -----------------
checkAccount(false)
</script>
<style scoped lang="less">
iframe {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
</style>
